package com.jmu.medicineknows.service.impl;

import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jmu.medicineknows.dto.DrugPageDto;
import com.jmu.medicineknows.entity.*;
import com.jmu.medicineknows.mapper.DrugMapper;
import com.jmu.medicineknows.mapper.SaleRecordMapper;
import com.jmu.medicineknows.service.DrugService;
import io.netty.util.internal.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author: JieZi
 * @Date: 2023/7/12 09:14
 * @Description:
 **/
@Service
@SuppressWarnings("all")
public class DrugServiceImpl implements DrugService {

    public static final Set<String> fileSet = new HashSet<>();
    public SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    @Autowired
    public DrugMapper drugMapper;
    @Autowired
    public SaleRecordMapper saleRecordMapper;
    @Override
    public Result drugList(DrugPageDto drugPageDto) {
        Page <DrugInfo> page = new Page(drugPageDto.currentPage,drugPageDto.pageSize);
        LambdaQueryWrapper<DrugInfo>queryWrapper = new LambdaQueryWrapper<>();
        if(' ' != drugPageDto.getFlag() && !StringUtil.isNullOrEmpty(drugPageDto.content)){
            String cleanStr = drugPageDto.content.replaceAll("\\p{P}", " ");
            System.err.println(cleanStr);
            switch (drugPageDto.flag){
                case '1' : {
                    queryWrapper.like(DrugInfo::getName,drugPageDto.content);
                    break;
                }
                case '2' : {
                    queryWrapper.like(DrugInfo::getDrugFunction,drugPageDto.content)
                            .or().like(DrugInfo::getIndication,drugPageDto.content);
                    break;
                }
                case '3' : {
                    queryWrapper.like(DrugInfo::getComposition,drugPageDto.content);
                    break;
                }
                case '4': {
                    queryWrapper.eq(DrugInfo::getId,drugPageDto.content);
                    break;
                }
                case '5' :{
                    queryWrapper.like(DrugInfo::getPc,drugPageDto.content);
                    break;
                }
                default:break;
            }
        }
        if(!Objects.isNull(drugPageDto.getType())){
            queryWrapper.likeRight(DrugInfo::getUrl,drugPageDto.type);
        }
        IPage <DrugInfo> drugInfoIPage = drugMapper.selectPage(page, queryWrapper);
        drugInfoIPage.setRecords(filterList(drugInfoIPage.getRecords()));
        return Result.defaultSuccess(drugInfoIPage);
    }

    @Override
    public Result updateDrug(DrugInfo drugInfo) {
        LambdaQueryWrapper<DrugInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DrugInfo::getId,drugInfo.id);
        return Result.defaultSuccess(drugMapper.update(drugInfo,queryWrapper));
    }

    @Override
    public Result delete(Long id) {
        LambdaQueryWrapper<DrugInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DrugInfo::getId,id);
        return Result.defaultSuccess(drugMapper.delete(queryWrapper));
    }

    @Override
    public Result insert(DrugInfo drugInfo) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        drugInfo.setCreateTime(sdf.format(new Date()));
        drugInfo.setCreateBy(loginUser.getUser().getId());
        return Result.defaultSuccess(drugMapper.insert(drugInfo));
    }

    @Override
    public Result upload(MultipartFile file) {
        fileSet.add("drug");
        fileSet.add("pifu");
        fileSet.add("weichang");
        String originName = file.getOriginalFilename();
        String filePrefix = originName.substring(0,originName.indexOf("."));
        if(!fileSet.contains(filePrefix)){
            return Result.defaultFailure();
        }
        String fileName = filePrefix + UUID.randomUUID().toString() + new Random().nextInt(10)
                + originName.substring(originName.indexOf("."));
        String osName = System.getProperty("os.name");
        String rootPath = "";
        if("linux".equals(osName) || "mac".equals(osName)){
            rootPath = "/root/uploads/drug";
        }else {
            rootPath = "D://uploads/drug";
        }
        String filePath = rootPath + File.separator + fileName;
        File dir = new File(rootPath);
        if(!dir.exists()){
            dir.mkdirs();
        }
        try {
            file.transferTo(new File(filePath));
        }catch (Exception e){
            e.printStackTrace();
        }
        return Result.defaultSuccess(fileName);
    }

    public List<DrugInfo> filterList(List<DrugInfo> list){
        list.forEach((item)->{
            Object o = saleRecordMapper.selectSaleCount(item.name);
            BigDecimal decimal = (BigDecimal) (o);
            int saleNum = 0;
            if(!Objects.isNull(o)){
                saleNum = Integer.parseInt(decimal.toString());
            }
            InfoDetail infoDetail = new InfoDetail();
            infoDetail.indication = item.indication;
            infoDetail.drugFunction = item.drugFunction;
            infoDetail.illustrate = item.illustrate;
            infoDetail.composition = item.composition;
            infoDetail.setCreateBy(item.getCreateBy());
            infoDetail.setCreateTime(item.getCreateTime());
            item.infoDetailList.add(infoDetail);
            item.saleNum = saleNum;
            infoDetail.setApprovalNo(item.approvalNo);
            infoDetail.setPc(item.pc);
            infoDetail.setSaleCount(item.saleNum * item.price);
        });
        return list;
    }
}